package com.example.consumer.service.impl;

import com.example.consumer.pojo.Order;
import com.example.consumer.pojo.Product;
import com.example.consumer.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.client.RestTemplate;

import java.util.List;

/**
 * description: OrderServiceImpl <br>
 * date: 2021/5/25 11:53 <br>
 * author: xiehui <br>
 * version: 1.0 <br>
 * <p>
 * <p>
 * <p>
 * <p>
 * 对于服务的消费用以下3种方式：
 * <p>
 * DiscoveryClient：通过元数据获取服务信息
 * LoadBalancerClient：ribbon的负载均衡器
 *
 * @LoadBalanced ：通过注解开启ribbon的负载均衡器
 */
@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    @Qualifier("restTemplate")
    RestTemplate restTemplate;

    @Autowired
    @Qualifier("restTemplateByLoadBalanced")
    RestTemplate restTemplateByLoadBalanced;

    @Autowired
    DiscoveryClient discoveryClient;

    @Autowired
    LoadBalancerClient loadBalancerClient;


    @Override
    public Order selectOrderById(String orderid) {
        if ("1".equals(orderid)) {
            return new Order("1", discoveryClient());
        }
        if ("2".equals(orderid)) {
            return new Order("2", loadBalancerClient());
        }
        if ("3".equals(orderid)) {
            return new Order("3", loadBalanced());
        }

        return null;
    }


    private List<Product> discoveryClient() {
        System.out.println("discoveryClient的方式.............");
        System.out.println();
        StringBuffer stringBuffer = null;

        // 服务列表
        List<String> services = discoveryClient.getServices();
        if (CollectionUtils.isEmpty(services))
            return null;

        // 根据服务名称获取服务
        List<ServiceInstance> instances = discoveryClient.getInstances("service-provider");
        if (CollectionUtils.isEmpty(instances))
            return null;

        ServiceInstance serviceInstance = instances.get(0);
        stringBuffer = new StringBuffer();
        stringBuffer.append("http://" + serviceInstance.getHost() + ":" + serviceInstance.getPort() + "/product/list");

        ResponseEntity<List<Product>> responseEntity = restTemplate.exchange(
                stringBuffer.toString(),
                HttpMethod.GET,
                null,
                new ParameterizedTypeReference<List<Product>>() {
                }
        );

        return responseEntity.getBody();
    }


    private List<Product> loadBalancerClient() {
        System.out.println("loadBalancerClient的方式.............");
        System.out.println();
        StringBuffer sb = null;

        ServiceInstance serviceInstance = loadBalancerClient.choose("service-provider");
        if (serviceInstance == null)
            return null;
        sb = new StringBuffer();
        sb.append("http://" + serviceInstance.getHost() + ":" + serviceInstance.getPort() + "/product/list");
        System.out.println(sb.toString());

        ResponseEntity<List<Product>> responseEntity = restTemplate.exchange(
                sb.toString(),
                HttpMethod.GET,
                null,
                new ParameterizedTypeReference<List<Product>>() {
                }
        );

        return responseEntity.getBody();
    }


    private List<Product> loadBalanced() {
        System.out.println("loadBalanced注解的方式.............");
        System.out.println();
        ResponseEntity<List<Product>> responseEntity = restTemplateByLoadBalanced.exchange(
                "http://service-provider/product/list",
                HttpMethod.GET,
                null,
                new ParameterizedTypeReference<List<Product>>() {
                }
        );
        return responseEntity.getBody();
    }


}
